package com.sniff.atp.service.wms.stock;

import com.ckbs.global.common.utils.CopyUtils;
import com.ckbs.wms.client.dto.resp.DeliverTaskRespDTO;
import com.ckbs.wms.client.dto.resp.DeliveryPkgDTO;
import com.ckbs.wms.client.dto.resp.DeliveryTaskAddressRespDTO;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ckbs.wms.common.enums.AddressTypeEnum;
import com.ckbs.wms.common.enums.DeliveryStatusEnum;
import com.ckbs.wms.common.enums.DeliveryTypeEnum;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sniff.atp.constant.LoginConstant;
import com.sniff.atp.dto.ClientLoginDTO;
import com.sniff.atp.dto.ContentDTO;
import com.sniff.atp.dto.WMSLoginDTO;
import com.sniff.atp.dto.request.ManagerConfirmReqDTO;
import com.sniff.atp.dto.request.StockOutDTO;
import com.sniff.atp.dto.wms.BatchDeliveryDeductionDto;
import com.sniff.atp.dto.wms.D2cAllotProgressInfoDTO;
import com.sniff.atp.dto.wms.D2cAllotProgressRespDTO;
import com.sniff.atp.dto.wms.DeliveryWaveCreateReq;
import com.sniff.atp.enums.api.OrderAPI;
import com.sniff.atp.enums.api.WmsAPI;
import com.sniff.atp.enums.sql.SniffSql;
import com.sniff.atp.enums.status.DeliverStatus;
import com.sniff.atp.enums.status.DeliverType;
import com.sniff.atp.enums.status.PickType;
import com.sniff.atp.service.wms.storage.WMSStorageService;
import com.sniff.atp.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.testng.Assert;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @BelongsProject: sniff-atp
 * @Author: ljj
 * @CreateTime: 2022/11/8 9:32
 * @Description:
 * @Version: 1.0
 */
@Service
@Slf4j
public class WmsStockOutService {

    private Logger logger = LoggerFactory.getLogger(WmsStockOutService.class);

    private Gson gson = new GsonBuilder()
            .registerTypeAdapter(Date.class, new CustomDateDeserializer())
            .create();

    @Autowired
    private WmsStockOutService wmsStockOutService;

    @Autowired
    private WMSStorageService wmsStorageService;

    @Value("${sniff.wms.username}")
    private String wmsUsername;

    public void switchHeaderByWarehouse(WMSLoginDTO wmsLoginDTO,String orderNo){
        String res =  DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单",new ContentDTO("",orderNo),new ContentDTO("",orderNo)).toJSONString();
        String warehouse = JsonUtil.extractString(res,"warehouse");
        wmsStorageService.switchHouse(wmsLoginDTO,warehouse);
    }


    /**
     * 根据订单号查询订单信息
     * @param orderNo
     * @param wmsLoginDTO
     */
    public void switchHeaderByWarehouseOrderNo(WMSLoginDTO wmsLoginDTO,String orderNo){
        String res =  DBUtil.selectOne("ORDER-根据订单号查寻订单信息",new ContentDTO("",orderNo)).toJSONString();
        String warehouse = JsonUtil.extractString(res,"ware_code");
        wmsStorageService.switchHouse(wmsLoginDTO,warehouse);
    }

    /**
     * 创建国际发货单并出库流程
     * @param clientLoginDTO
     * @param wmsLoginDTO
     * @param productInfo
     */
    public String stockOut(ClientLoginDTO clientLoginDTO,WMSLoginDTO wmsLoginDTO,JSONObject productInfo){
        String deliveryTitle = "LJJZFTest" + new Date().getTime();
        createOrderProcessM(clientLoginDTO,deliveryTitle,productInfo);
        String res = getGjfhOrderNo(clientLoginDTO,deliveryTitle);
        String deliveryTaskCode = JsonUtil.extractString(res, "data.records[0].deliveryTaskCode");
        String warehouse = JsonUtil.extractString(res, "data.records[0].warehouse");
        wmsStorageService.switchHouse(wmsLoginDTO,warehouse);
        examineGJFH(wmsLoginDTO,DeliverType.BIG.getType(), deliveryTaskCode);
        createPickTask(wmsLoginDTO,DeliverType.BIG.getType(),PickType.BIG.getType(),deliveryTaskCode);
        picking(wmsLoginDTO,DeliverType.BIG.getType(),deliveryTaskCode);
        packing(wmsLoginDTO,DeliverType.BIG.getType(),deliveryTaskCode);
        //获取当前库存剩余数及发货总数
        Integer nums = getDeliverNums(wmsLoginDTO,deliveryTaskCode,DeliverType.BIG.getType());
        Integer remainAmounts = getRemainAmounts(wmsLoginDTO,deliveryTaskCode,DeliverType.BIG.getType(),DeliverStatus.DELIVER_STATUS4);
        confirmStock(wmsLoginDTO,deliveryTaskCode);
        res = confirmSign(clientLoginDTO,deliveryTaskCode);
        Assert.assertEquals(getRemainAmounts(wmsLoginDTO,deliveryTaskCode,DeliverType.BIG.getType(),DeliverStatus.DELIVER_STATUS5),remainAmounts-nums,"出库数量不匹配");
        return res;
    }

    /**
     * 国际发货单并出库流程
     * @param deliveryTaskCode
     * @param operationNode
     */
    public JSONObject deliveryStockOut(WMSLoginDTO wmsLoginDTO, String deliveryTaskCode, Integer operationNode){
        JSONObject res = new JSONObject();

        logger.info("一键发货-- deliveryType:{} operationNode：{}  ", deliveryTaskCode, operationNode);

        if (deliveryTaskCode == null || StringUtils.isEmpty(deliveryTaskCode) || "null".equals(deliveryTaskCode)) {
            res.put("operationNode", "国际发货单为空");
            return res;
        }

        if(operationNode == null || operationNode == 0){
            operationNode = 6;
        }

        //通过sql查询发货单,获取deliverType和pickType和needLabel
        JSONObject sqlRes = DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单", new ContentDTO("", deliveryTaskCode));
        if (sqlRes == null || sqlRes.isEmpty()) {
            res.put("operationNode", "发货单不存在");
            return res;
        }
        Long customerShopId = sqlRes.getLong("customer_shop_id");
        Integer deliverType = sqlRes.getInteger("delivery_type");
        Integer singleProduct = sqlRes.getInteger("single_product");
        Integer needLabel = sqlRes.getInteger("need_label");
        Integer deliveryStatus = sqlRes.getInteger("delivery_status");
        Integer pickType;
        if (deliverType == 0) {
            //FBA拣货
            pickType = 3;
        } else if (deliverType == 1) {
            //大件拣货
            pickType = 0;
        } else {
            if (singleProduct == 0) {
                //小件多品拣货
                pickType = 2;
            } else {
                //小件单品拣货
                pickType = 1;
            }
        }


        //切换仓库
        wmsStockOutService.switchHeaderByWarehouse(LoginConstant.wmsLoginDTO,deliveryTaskCode);
        //担当确认
        managerConfirm(wmsLoginDTO,deliveryTaskCode);
        //获取审单信息
        List<JSONObject> wmsDeliveryReview = DBUtil.select("WMS-根据国际发货号查寻审单信息", new ContentDTO("", deliveryTaskCode));
        String processingStatus = wmsDeliveryReview.get(0).getString("processing_status");
        if("0".equals(processingStatus)){
            //审单
            examineGJFH(wmsLoginDTO,deliverType, deliveryTaskCode);
        }
        res.put("operationNode", "分单完成");

        if(operationNode == 1){
            return res;
        }

        //国际发货单抵扣,等待国际发货单更新为待处理状态
        for(int i=1 ;i<=25;i++) {
            logger.info("循环第几次:{}", i);
            //通过sql查询发货单
            sqlRes = DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单", new ContentDTO("", deliveryTaskCode));
            deliveryStatus = sqlRes.getInteger("delivery_status");

            logger.info("deliveryStatus:{}", deliveryStatus);
            if (deliveryStatus > -1) {
                break;
            }
            //首次循环
            if(deliveryStatus == -1 && i == 1) {
                //触发国际发货单抵扣
                List<String> deliveryTaskCodeList = new ArrayList<>(Collections.singletonList(deliveryTaskCode));
                BatchDeliveryDeductionDto batchDeliveryDeductionDto = new BatchDeliveryDeductionDto();
                batchDeliveryDeductionDto.setCustomerShopId(customerShopId);
                batchDeliveryDeductionDto.setDeliveryTaskCodeList(deliveryTaskCodeList);
                wmsStockOutService.batchDeliveryTaskDeduction(wmsLoginDTO, batchDeliveryDeductionDto);
            }

            if(i == 25){
                res.put("operationNode", "国际发货单抵扣失败");
                return res;
            }

            //等待3秒
            ToolsUtil.sleep(3000);
        }

        //创建拣货任务
        if(deliveryStatus == 0){
            createPickTask(wmsLoginDTO,deliverType,pickType,deliveryTaskCode);
        }
        res.put("operationNode", "待拣货");

        if(operationNode == 2){
            return res;
        }
        //拣货
        sqlRes =  DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单",new ContentDTO("",deliveryTaskCode),new ContentDTO("",deliveryTaskCode));
        deliveryStatus = sqlRes.getInteger("delivery_status");
        if(deliveryStatus == 1){
            picking(wmsLoginDTO, deliverType, deliveryTaskCode);
        }
        res.put("operationNode", "拣货完成");
        if(operationNode == 3){
            return res;
        }

        //打标
        sqlRes =  DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单",new ContentDTO("",deliveryTaskCode),new ContentDTO("",deliveryTaskCode));
        deliveryStatus = sqlRes.getInteger("delivery_status");
        if(needLabel == 1 && deliveryStatus == 2){
            markFinish(wmsLoginDTO, deliveryTaskCode);
        }
        res.put("operationNode", "打标完成");
        if(operationNode == 4){
            return res;
        }

        //打包
        sqlRes =  DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单",new ContentDTO("",deliveryTaskCode),new ContentDTO("",deliveryTaskCode));
        deliveryStatus = sqlRes.getInteger("delivery_status");
        if(deliveryStatus == 3){
            packing(wmsLoginDTO, deliverType, deliveryTaskCode);
        }
        res.put("operationNode", "打包完成");
        //下载装箱清单
        downloadCustomerPackingListFile(wmsLoginDTO, deliveryTaskCode);
        //下载箱唛
        downloadCustomerBoxMarkFile(wmsLoginDTO, deliveryTaskCode);

        if(operationNode == 5){
            return res;
        }
        //获取当前库存剩余数及发货总数
        Integer nums = getDeliverNums(wmsLoginDTO, deliveryTaskCode, deliverType);
        Integer remainAmounts = getRemainAmounts(wmsLoginDTO,deliveryTaskCode,deliverType,DeliverStatus.DELIVER_STATUS4);

        //确认发货
        confirmStock(wmsLoginDTO,deliveryTaskCode);
        Assert.assertEquals(getRemainAmounts(wmsLoginDTO,deliveryTaskCode,deliverType,DeliverStatus.DELIVER_STATUS5),remainAmounts-nums,"出库数量不匹配");
        res.put("operationNode", "发货完成");
        return res;
    }

    /**
     * D2C出库流程
     * @param wmsLoginDTO
     * @param deliveryType
     * @param orderNo
     */
    public String stockOutD2c(WMSLoginDTO wmsLoginDTO,Integer deliveryType,String orderNo){

        examineGJFH(wmsLoginDTO,deliveryType,orderNo);
        String res = searchTaskPage(wmsLoginDTO,orderNo,DeliverStatus.DELIVER_STATUS0, deliveryType);
        String deliveryTaskCode = JsonUtil.extractString(res, "data.records[0].deliveryTaskCode");
        createPickTask(wmsLoginDTO,deliveryType,PickType.SMALL_MANY.getType(),deliveryTaskCode);
        picking(wmsLoginDTO,deliveryType,deliveryTaskCode);
        packing(wmsLoginDTO,deliveryType,deliveryTaskCode);
        //获取当前库存剩余数及发货总数
        Integer nums = getDeliverNums(wmsLoginDTO,deliveryTaskCode,deliveryType);
        Integer remainAmounts = getRemainAmounts(wmsLoginDTO,deliveryTaskCode,deliveryType,DeliverStatus.DELIVER_STATUS4);
        res = confirmStock(wmsLoginDTO,deliveryTaskCode);
        Assert.assertEquals(getRemainAmounts(wmsLoginDTO,deliveryTaskCode,deliveryType,DeliverStatus.DELIVER_STATUS5),remainAmounts-nums,"出库数量不匹配");
        return res;
    }

    /**
     * D2C出库流程到指定位置
     * @param wmsLoginDTO
     * @param stockOutDTO
     */
    public String stockOutD2cStep(WMSLoginDTO wmsLoginDTO, StockOutDTO stockOutDTO){


        String res = "{\"code\":9999,\"msg\":\"订单号与发货类型必传\"}";

        //有发货单号的使用发货单号，没有发货单号的使用订单编号
        String orderNo = "";
        //发货类型(fba发货0,大包发货1,小包发货2)
        Integer deliveryType = stockOutDTO.getDeliverType();
        //审单1，生成拣货任务2，pda拣货3，打包完成4，确认发货5
        String operationNote = stockOutDTO.getOperationNote();

        if ((stockOutDTO.getDeliverType()!=null&&stockOutDTO.getPlatformOrderNo()!=null)&&(!"".equals(stockOutDTO.getPlatformOrderNo()))){

            //看有没有发货单号，没有发货单号的通过订单查询
            if(StringUtils.isNotEmpty(stockOutDTO.getDeliveryTaskCode())){
                wmsStockOutService.switchHeaderByWarehouse(LoginConstant.wmsLoginDTO,stockOutDTO.getDeliveryTaskCode());
                orderNo = stockOutDTO.getDeliveryTaskCode();
            }else{
                wmsStockOutService.switchHeaderByWarehouseOrderNo(LoginConstant.wmsLoginDTO,stockOutDTO.getPlatformOrderNo());
                orderNo = stockOutDTO.getPlatformOrderNo();
            }
//            wmsStockOutService.switchHeaderByWarehouse(LoginConstant.wmsLoginDTO,stockOutDTO.getPlatformOrderNo());
        }


        logger.info("一键发货-- deliveryType:{} orderNo:{} operationNote：{}  ", deliveryType, orderNo, operationNote);

        //看步骤是不是空，为空的直接走完,审单1，生成拣货任务2，pda拣货3，打包完成4，确认发货5
        if(StringUtils.isEmpty(operationNote)){
            operationNote = "5";
        }

        //审单完结获取发货单号
        String deliveryTaskCode = "";
        // 查询审单状态
        List<JSONObject> wmsDeliveryReview = DBUtil.select("WMS-根据订单号查寻发货单订单信息", new ContentDTO("", orderNo));
        String processingStatus = wmsDeliveryReview.get(0).getString("processing_status");
        if("0".equals(processingStatus)){
            //审单
            examineGJFH(wmsLoginDTO,deliveryType,orderNo);
        }
        for(int i=0 ;i<15;i++){
            logger.info("循环第几次:{}",i);
            ToolsUtil.sleep(5000);
            res = searchTaskPage(wmsLoginDTO,orderNo,DeliverStatus.DELIVER_STATUS0, deliveryType);
            deliveryTaskCode = JsonUtil.extractString(res, "data.records[0].deliveryTaskCode");
            logger.info("deliveryTaskCode:{}",deliveryTaskCode);
            if (deliveryTaskCode != null && StringUtils.isNotEmpty(deliveryTaskCode) && !deliveryTaskCode.equals("null")){
                break;
            }
        }

        //通过sql查询发货单号
//        JSONObject object = DBUtil.selectOne("WMS-根据订单号查寻发货单订单信息", new ContentDTO("", orderNo));
//        deliveryTaskCode = object.getString("delivery_task_code");



        if(operationNote.equals("1")){
            return res;
        }
        //生成拣货任务
        res = searchTaskPage(wmsLoginDTO,deliveryTaskCode,DeliverStatus.DELIVER_STATUS0, deliveryType);
        String singleProduct = JsonUtil.extractString(res, "data.records[0].singleProduct");
        Boolean isJpnAddress = JsonUtil.extractJSONArray(res,"data.records[0].deliveryTaskAddressList").stream().anyMatch(t -> ((JSONObject) t).getString("addressType").equals("0"));
        if(singleProduct.equals("1")){
            res = createPickTask(wmsLoginDTO,deliveryType,PickType.SMALL_ONE.getType(),deliveryTaskCode);
        }else {
            res = createPickTask(wmsLoginDTO,deliveryType,PickType.SMALL_MANY.getType(),deliveryTaskCode);
        }
        if(operationNote.equals("2")){
            return res;
        }

        //pda拣货

        res = picking(wmsLoginDTO,deliveryType,deliveryTaskCode);
        if(operationNote.equals("3")){
            return res;
        }

        //修改货代公司
        if(isJpnAddress){
            //收货地址类型为日本
            modifyForwarder(wmsLoginDTO,deliveryTaskCode,"80");
        }else{
            //收货地址类型为非日本
            modifyForwarder(wmsLoginDTO,deliveryTaskCode,"80");
        }

        //打包完成
        res = packing(wmsLoginDTO,deliveryType,deliveryTaskCode);
        if(operationNote.equals("4")){
            return res;
        }

        //获取当前库存剩余数及发货总数
        Integer nums = getDeliverNums(wmsLoginDTO,deliveryTaskCode,deliveryType);
        Integer remainAmounts = getRemainAmounts(wmsLoginDTO,deliveryTaskCode,deliveryType,DeliverStatus.DELIVER_STATUS4);

        //确认出库
        res = confirmStock(wmsLoginDTO,deliveryTaskCode);
        Assert.assertEquals(getRemainAmounts(wmsLoginDTO,deliveryTaskCode,deliveryType,DeliverStatus.DELIVER_STATUS5),remainAmounts-nums,"出库数量不匹配");
        return res;
    }

    /**
     * 给定一个发货单号或平台单号进行审核新
     * @param wmsLoginDTO
     * @param deliveryType
     * @param orderNo
     * @return
     */
    public String examineGJFH(WMSLoginDTO wmsLoginDTO,Integer deliveryType,String orderNo){
        String res = getDeliveryReviewCode(wmsLoginDTO,deliveryType,orderNo);
        JSONObject params = new JSONObject();
        String deliveryTaskCode = JsonUtil.extractString(res,"data.deliveryReviewPage.records[0].deliveryTaskCode");
        String deliveryReviewCode = JsonUtil.extractString(res,"data.deliveryReviewPage.records[0].deliveryReviewCode");
        params.put("deliveryReviewCode",deliveryReviewCode);
        params.put("deliveryType",deliveryType);
        params.put("deliveryTaskCode",deliveryTaskCode);
        //查看审核单详情
        res = deliverReviewInfo(wmsLoginDTO,params);
        params = new JSONObject();
        params.put("auditForwarder",JsonUtil.extractString(res,"data.logisticsChoose.forwarder"));
        params.put("auditIntForwarderConfigId",JsonUtil.extractString(res,"data.logisticsChoose.intForwarderConfigId"));
        params.put("auditIntShipConfigId",JsonUtil.extractString(res,"data.auditIntShipConfigId"));
        params.put("auditRemark","审单备注");
        params.put("auditShippingType",JsonUtil.extractString(res,"data.logisticsChoose.shippingType"));
        params.put("auditType",0);
        params.put("deliveryReviewCode",deliveryReviewCode);
        params.put("intForwarderConfigId",JsonUtil.extractString(res,"data.logisticsChoose.intForwarderConfigId"));

        //审单
        res = singleReview(wmsLoginDTO,params);
        return res;
    }

    /**
     * 根据订单编号完成审单
     */
    public String deliveryReview(WMSLoginDTO wmsLoginDTO, Integer deliveryType, String platformOrderNos, String... deliveryTaskCodes){
        JSONObject params = new JSONObject();
        String res = "";
        params.put("deliveryTaskCodes",Arrays.asList(deliveryTaskCodes));

        // 查询审单列表信息
        res = searchReviewPage(wmsLoginDTO,platformOrderNos,deliveryType);
        System.out.println(res);


        for (int i=0;i<deliveryTaskCodes.length;i++){
            res = searchTaskPage(wmsLoginDTO,deliveryTaskCodes[i], DeliverStatus.DELIVER_STATUS0, deliveryType);
            JSONArray shopProductSkus = JsonUtil.extractJSONArray(res, "data.records[0].taskDetailList[*].shopProductSku");
            params.put("shopProductSkus",shopProductSkus);
//            pagePickingTaskNotListed(wmsLoginDTO,pickType,params);
//            pickCreate(wmsLoginDTO,pickType, Arrays.asList(deliveryTaskCodes));
        }return res;
    }


    /**
     * 根据发货单号生成拣货任务
     * @param deliveryTaskCodes 发货单列表
     */
    public String createPickTask(WMSLoginDTO wmsLoginDTO, Integer deliveryType, Integer pickType, String... deliveryTaskCodes){
        JSONObject params = new JSONObject();
        String res = "";
        params.put("deliveryTaskCodes",Arrays.asList(deliveryTaskCodes));

        for (int i=0;i<deliveryTaskCodes.length;i++){
            res = searchTaskPage(wmsLoginDTO,deliveryTaskCodes[i], DeliverStatus.DELIVER_STATUS0, deliveryType);
            JSONArray shopProductSkus = JsonUtil.extractJSONArray(res, "data.records[0].taskDetailList[*].shopProductSku");
            params.put("shopProductSkus",shopProductSkus);
            pagePickingTaskNotListed(wmsLoginDTO,pickType,params);
            pickCreate(wmsLoginDTO,pickType, Arrays.asList(deliveryTaskCodes));
        }return res;
    }

    /**
     * 根据发货单号和批次号进行拣货
     * @param deliveryTaskCode 发货单号
     */
    public String picking(WMSLoginDTO wmsLoginDTO,Integer deliveryType,String deliveryTaskCode){
        String res = searchTaskPage(wmsLoginDTO,deliveryTaskCode,DeliverStatus.DELIVER_STATUS1, deliveryType);
        int sum = 0;
        JSONArray nums = JsonUtil.extractJSONArray(res, "data.records[*].deliveryNums");
        for (int i=0;i<nums.size();i++){
            sum+=nums.getIntValue(i);
        }
        List<String> batchCodes = new ArrayList<>();
        JSONArray pkgCodeLists = JsonUtil.extractJSONArray(res, "data.records[0].taskDetailList[*].pkgCodeList");
        for (int i=0;i<pkgCodeLists.size();i++){
            batchCodes.addAll(pkgCodeLists.getJSONArray(i));
        }
        List<JSONObject> jsonObjects = DBUtil.select("WMS-拣货任务查询", new ContentDTO("", deliveryTaskCode));
        for (JSONObject js:jsonObjects){
            String pickTaskCode = js.getString("pick_task_code");
            for (int i=0;i<batchCodes.size();i++){
                //开始拣货
                picked(wmsLoginDTO,pickTaskCode,batchCodes.get(i));
            }
            //拣货完成
            res = pickFinish(wmsLoginDTO,pickTaskCode);
            //开始配货
            if (jsonObjects.get(0).getInteger("pick_type")==2&&deliveryType.equals(DeliverType.SMALL.getType())){
                for (int i=0;i<sum;i++){
                    getD2cAllotProgress(wmsLoginDTO,pickTaskCode);
                }
                //配货完成
                res = allotFinish(wmsLoginDTO,pickTaskCode);
            }
        }return res;
    }

    /**
     * 给定发货单号进行打标
     * @param deliveryTaskCode
     */
    public String markFinish(WMSLoginDTO wmsLoginDTO, String deliveryTaskCode){
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        LogUtil.info("【wms出库】打标完成");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API57.getApi(),params);
    }

    /**
     * 给定发货单号进行打包
     * @param deliveryTaskCode
     */
    public String packing(WMSLoginDTO wmsLoginDTO,Integer deliveryType,String deliveryTaskCode){
        String res = null;
        if (deliveryType == DeliverType.SMALL.getType()){
            res = logisticsDetail(wmsLoginDTO,deliveryTaskCode);
            String deliveryBoxId = JsonUtil.extractString(res,"data[0].deliveryBoxList[0].deliveryBoxId");
            String insidePackCode = JsonUtil.extractString(res,"data[0].deliveryBoxList[0].insidePackCode");
            //d2c编辑重量
            weightEdit(wmsLoginDTO,deliveryBoxId,deliveryTaskCode,insidePackCode);
            packFinsh(wmsLoginDTO,deliveryTaskCode);
        }else if (deliveryType == DeliverType.BIG.getType()){
            res = getPacking(wmsLoginDTO,deliveryTaskCode,DeliverStatus.DELIVER_STATUS3);
            String json = JsonUtil.extractString(res, "data");
            DeliverTaskRespDTO deliverTaskRespDTO = gson.fromJson(json, DeliverTaskRespDTO.class);
            List<DeliveryPkgDTO> pkgPackList = deliverTaskRespDTO.getPkgPackList();
            if (pkgPackList.size() == 0){
                return res;
            }
            for(int i=0;i<pkgPackList.size();i++){
                DeliveryPkgDTO pkgPackDTO = pkgPackList.get(i);
                //添加容器
                logisticsEdit(wmsLoginDTO,deliveryTaskCode,null);
                String response = logisticsDetail(wmsLoginDTO, deliveryTaskCode);
                String insidePackCode = JsonUtil.extractString(response,"data["+ i +"].insidePackCode");
                String deliveryTaskLogisticsDetailId = JsonUtil.extractString(response,"data["+ i +"].deliveryTaskLogisticsDetailId");

                //添加物流单号
                logisticsEdit(wmsLoginDTO,deliveryTaskCode,deliveryTaskLogisticsDetailId);

                //添加箱子
                boxEdit(wmsLoginDTO,deliveryTaskCode,insidePackCode);
                String logisticsDetail = logisticsDetail(wmsLoginDTO,deliveryTaskCode);
                String deliveryBoxCode = JsonUtil.extractString(logisticsDetail,"data["+ i +"].deliveryBoxList[0].deliveryBoxCode");

                //添加商品
                JSONObject params = new JSONObject();
                params.put("deliveryBoxCode",deliveryBoxCode);
                params.put("deliveryTaskCode",deliveryTaskCode);
                params.put("insidePackCode",insidePackCode);
                params.put("shopProductSku",pkgPackDTO.getShopProductSku());
                params.put("pkgCode",pkgPackDTO.getPkgCode());
                params.put("nums",pkgPackDTO.getTotalNums()-pkgPackDTO.getInNums());
                editWithPkg(wmsLoginDTO,params);
            }
            //完成装箱
            res = packFinsh(wmsLoginDTO,deliveryTaskCode);
        }
        return res;
    }

    /**
     * 给定发货单号下载装箱清单
     * @param deliveryTaskCode
     */
    public String downloadCustomerPackingListFile(WMSLoginDTO wmsLoginDTO, String deliveryTaskCode){
        //确认发货
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        LogUtil.info("【wms出库】下载装箱清单完成");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API58.getApi(),params);
    }

    /**
     * 给定发货单号下载箱唛
     * @param deliveryTaskCode
     */
    public String downloadCustomerBoxMarkFile(WMSLoginDTO wmsLoginDTO, String deliveryTaskCode){
        //确认发货
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        LogUtil.info("【wms出库】下载箱唛完成");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API59.getApi(),params);
    }

    /**
     * 给定发货单号发货完成
     * @param deliveryTaskCode
     */
    public String deliveryCompleted(WMSLoginDTO wmsLoginDTO,Integer deliveryType,String deliveryTaskCode){
        String res = searchTaskPage(wmsLoginDTO,deliveryTaskCode,DeliverStatus.DELIVER_STATUS3, deliveryType);
        //确认发货
        return confirmStock(wmsLoginDTO,deliveryTaskCode);
    }

    /**
     * 查询店铺商品列表信息
     * @param shopProductSku 店铺sku
     * @return
     */
    private String searchProduct(ClientLoginDTO clientLoginDTO,String shopProductSku){
        Map<String,String> params = new HashMap<>();
        params.put("keywordSku",shopProductSku);
        LogUtil.info("【b2b电商】查询国际发货单信息");
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO)).doGet(OrderAPI.SHOP_PRODUCT_LIST.getApi(), params);
    }

    /**
     * 国际发货单查询
     * @param deliveryStatus 发货单状态
     * @param deliveryTaskCode 发货单号
     * @return
     */
    public String searchTaskPage(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode,DeliverStatus deliveryStatus,Integer deliveryType){
        JSONObject params = JsonUtil.readJson("wms/stock/taskPage");
        if (deliveryType==DeliverType.SMALL.getType()&&!deliveryTaskCode.startsWith("GJFH")){
            params.replace("platformOrderNoStr",deliveryTaskCode);
        }else {
            params.replace("deliveryTaskCode",deliveryTaskCode);
        }
        if(deliveryStatus != null){
            params.replace("deliveryStatus",deliveryStatus.getStatus());
        }
        params.replace("deliveryType",deliveryType);
        LogUtil.info("【wms出库】查询发货单详情信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API13.getApi(), params);
    }

    private String createGJFHOrder(ClientLoginDTO clientLoginDTO,String deliveryTitle,List<JSONObject> deliverTaskDetails) {
        JSONObject param = JsonUtil.readJson("wms/stock/createGjfhStockOut");
        int sum = 0;
        for (JSONObject jsonObject:deliverTaskDetails){
            sum += jsonObject.getInteger("deliveryNums");
        }
        param.put("deliverTaskDetails", deliverTaskDetails);
        param.put("deliveryNums",sum);
        param.replace("deliveryTitle",deliveryTitle);
        String result = new HttpClientUtil(Headers.setClientHeader(clientLoginDTO)).doPostJson(OrderAPI.GJFH_ORDER_CREATE.getApi(), param);
        LogUtil.info("【b2b电商】创建国际发货单");
        return result;
    }


    /**
     * GJFH: 创建国际发货订单流程
     * @param deliveryTitle 国际发货标题
     * @param productInfo key为shopProductSku，value为下单数量
     * @return
     */
    public String createOrderProcessM(ClientLoginDTO clientLoginDTO,String deliveryTitle,JSONObject productInfo)  {
        List<JSONObject> deliverTaskDetails = new ArrayList<>();

        Set<String> productSkus = productInfo.keySet();
        for (String sku:productSkus){
            JSONObject deliverDetail = new JSONObject();
            String s = searchProduct(clientLoginDTO,sku);
            deliverDetail.put("shopProductSku",JsonUtil.extractString(s, "data[0].shopProductSku"));
            deliverDetail.put("productSku",JsonUtil.extractString(s, "data[0].productSku"));
            deliverDetail.put("deliveryNums",productInfo.getInteger(sku));
            deliverTaskDetails.add(deliverDetail);
        }
        LogUtil.info("【订单流程】根据商品sku查询商品信息：" + productInfo);
        String order = createGJFHOrder(clientLoginDTO,deliveryTitle,deliverTaskDetails);
        LogUtil.info("【订单流程】创建订单成功，返回数据：" + order);
        return order;
    }


    /**
     * 生成拣货任务前检查
     * @param wmsLoginDTO
     * @param jsonObject
     * @return
     */
    private String pagePickingTaskNotListed(WMSLoginDTO wmsLoginDTO,Integer pickType,JSONObject jsonObject){
        JSONObject params = JsonUtil.readJson("wms/stock/pagePickingTaskNotListed");
        params.replace("deliveryTaskCodes",jsonObject.getJSONArray("deliveryTaskCodes"));
        params.replace("shopProductSkus",jsonObject.getJSONArray("shopProductSkus"));
        params.replace("pickType",pickType);
        LogUtil.info("【wms出库】生成拣货任务前检查");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API38.getApi(), params);
    }

    /**
     * 生成拣货任务
     * @param pickType 拣货任务类型
     * @param deliveryTaskCodeList 发货单号列表
     * @return
     */
    private String pickCreate(WMSLoginDTO wmsLoginDTO,Integer pickType,List<String> deliveryTaskCodeList){
        JSONObject params = new JSONObject();
        params.put("pickType",pickType);
        params.put("deliveryTaskCodeList",deliveryTaskCodeList);
        LogUtil.info("【wms出库】生成拣货任务");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API39.getApi(), params);
    }

    /**
     * 根据发货单标题查询国际发货单号
     * @param deliveryTitle
     * @return
     */
    private String getGjfhOrderNo(ClientLoginDTO clientLoginDTO,String deliveryTitle){
        JSONObject params = new JSONObject();
        params.put("deliveryTitle",deliveryTitle);
        String result = new HttpClientUtil(Headers.setClientHeader(clientLoginDTO)).doPostJson(OrderAPI.GJFH_ORDER_LIST.getApi(),params);
        LogUtil.info("国际发货单列表查询："+result);
        return result;
    }

    /**
     * 根据发货单号或者平台订单编号查询审核单code
     * @param wmsLoginDTO
     * @param deliveryType
     * @param orderNo
     * @return
     */
    private String getDeliveryReviewCode(WMSLoginDTO wmsLoginDTO,Integer deliveryType,String orderNo){
        JSONObject params = JsonUtil.readJson("wms/stock/deliveryPage");
        if (deliveryType==DeliverType.SMALL.getType()){
            params.put("platformOrderNo",orderNo);
        }else {
            params.put("deliveryTaskCode",orderNo);
        }
        params.put("deliveryType",deliveryType);
        LogUtil.info("【wms出库】根据发货单号或者平台订单编号查询审核单code");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API35.getApi(),params);
    }

    /**
     * 查询审核单详情
     * @param jsonObject
     * @return
     */
    private String deliverReviewInfo(WMSLoginDTO wmsLoginDTO,JSONObject jsonObject){
        JSONObject params = JsonUtil.readJson("wms/stock/reviewInfo");
        params.replace("deliveryType",jsonObject.get("deliveryType"));
        params.replace("deliveryReviewCode",jsonObject.get("deliveryReviewCode"));
        params.replace("deliveryTaskCode",jsonObject.get("deliveryTaskCode"));
        LogUtil.info("【wms出库】查询出库审核单详情信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API36.getApi(),params);
    }
    /**
     * 审核发货单
     * @param jsonObject
     * @return
     */
    private String singleReview(WMSLoginDTO wmsLoginDTO,JSONObject jsonObject){
        JSONObject params = JsonUtil.readJson("wms/stock/singleReview");

        params.replace("auditForwarder",jsonObject.get("auditForwarder"));
        params.replace("auditIntForwarderConfigId",jsonObject.get("auditIntForwarderConfigId"));
        params.replace("auditIntShipConfigId",jsonObject.get("auditIntShipConfigId"));
        params.replace("auditRemark",jsonObject.get("auditRemark"));
        params.replace("auditShippingType",jsonObject.get("auditShippingType"));
        params.replace("auditType",jsonObject.get("auditType"));
        params.replace("deliveryReviewCode",jsonObject.get("deliveryReviewCode"));
        params.replace("intForwarderConfigId",jsonObject.get("intForwarderConfigId"));
        LogUtil.info("【wms出库】审核国际发货单");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API37.getApi(), params);
    }
    /**
     * 确认发货
     * @param clientLoginDTO
     * @param deliveryTaskCode
     * @return
     */
    private String confirmReview(ClientLoginDTO clientLoginDTO,String deliveryTaskCode){
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        LogUtil.info("【wms出库】确认发货,发货单: "+deliveryTaskCode);
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO)).doPostJson(OrderAPI.ORDER_CONFIRMREVIEW.getApi(), params);
    }
    /**
     * 拣货
     * @param pickTaskCode 拣货任务号
     * @param pkgCode 批次号
     * @return
     */
    private String picked(WMSLoginDTO wmsLoginDTO,String pickTaskCode, String pkgCode){
        JSONObject params = new JSONObject();
        params.put("pickTaskCode",pickTaskCode);
        params.put("pkgCode",pkgCode);
        LogUtil.info("【PDA拣货】根据拣货任务号及批次号进行拣货");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API17.getApi(),params);
    }

    /**
     * 拣货完成
     * @param pickTaskCode 拣货任务号
     * @return
     */
    private String pickFinish(WMSLoginDTO wmsLoginDTO,String pickTaskCode){
        JSONObject params = new JSONObject();
        params.put("pickTaskCode",pickTaskCode);
        LogUtil.info("【PDA拣货】拣货完成");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API18.getApi(),params);
    }
    private String getD2cAllotProgress(WMSLoginDTO wmsLoginDTO,String pickTaskCode){
        JSONObject params = new JSONObject();
        params.put("pickTaskCode",pickTaskCode);
        LogUtil.info("【PDA配货】根据拣货任务号进行配货");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API49.getApi(),params);
    }
    private String allotFinish(WMSLoginDTO wmsLoginDTO,String pickTaskCode){
        JSONObject params = new JSONObject();
        params.put("pickTaskCode",pickTaskCode);
        LogUtil.info("【PDA配货】根据拣货任务号完成配货");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API50.getApi(),params);
    }
    /**
     * 查询物流详情信息
     * @param deliveryTaskCode
     * @return
     */
    private String logisticsDetail(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode){
        Map<String,String> params = new HashMap<>();
        params.put("deliveryTaskCode",deliveryTaskCode);
        LogUtil.info("【wms出库】查看物流详情信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API40.getApi(),params);
    }

    /**
     * 查看打包信息
     * @param deliveryTaskCode
     * @return
     */
    private String getPacking(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode,DeliverStatus deliveryStatus){
        Map<String,String> params = new HashMap<>();
        params.put("deliveryTaskCode",deliveryTaskCode);
        params.put("deliveryStatus",String.valueOf(deliveryStatus.getStatus()));
        LogUtil.info("【wms出库】查看出库打包信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API47.getApi(),params);
    }
    private String getSinglePacking(WMSLoginDTO wmsLoginDTO,String pkgCode){
        Map<String,String> params = new HashMap<>();
        params.put("pkgCode",pkgCode);
        LogUtil.info("【wms出库】查看单品打包信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API48.getApi(),params);
    }

    /**
     * 编辑物流单号
     * @param deliveryTaskCode 发货单号
     * @param deliveryTaskLogisticsDetailId 发货单物流详情id
     * @return
     */
    private String logisticsEdit(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode,String deliveryTaskLogisticsDetailId){
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        if (deliveryTaskLogisticsDetailId!=null&&!"".equals(deliveryTaskLogisticsDetailId)){
            params.put("deliveryTaskLogisticsDetailId",deliveryTaskLogisticsDetailId);
            params.put("logisticsCode","SF"+System.currentTimeMillis());
        }
        LogUtil.info("【wms出库】打包编辑物流详情信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API41.getApi(),params);
    }

    /**
     * 打包新增箱子
     * @param deliveryTaskCode 发货单号
     * @param insidePackCode
     * @return
     */
    private String boxEdit(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode,String insidePackCode){
        JSONObject params = JsonUtil.readJson("wms/stock/boxEdit");
        params.replace("deliveryTaskCode",deliveryTaskCode);
        params.replace("insidePackCode",insidePackCode);
        LogUtil.info("【wms出库】打包编辑箱子信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API42.getApi(),params);
    }

    /**
     * 打包新增商品
     * @param jsonObject
     * @return
     */
    private String productEdit(WMSLoginDTO wmsLoginDTO,JSONObject jsonObject){
        JSONObject params = new JSONObject();
        params.put("deliveryBoxCode",jsonObject.get("deliveryBoxCode"));
        params.put("deliveryTaskCode",jsonObject.get("deliveryTaskCode"));
        params.put("insidePackCode",jsonObject.get("insidePackCode"));
        params.put("shopProductSku",jsonObject.get("shopProductSku"));
        params.put("nums",jsonObject.get("nums"));
        LogUtil.info("【wms出库】打包编辑商品信息");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API43.getApi(),params);
    }

    /**
     * 打包新增商品pkg
     * @param jsonObject
     * @return
     */
    private String editWithPkg(WMSLoginDTO wmsLoginDTO,JSONObject jsonObject){
        LogUtil.info("【wms出库】打包编辑商品信息pkg");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API62.getApi(),jsonObject);
    }

    /**
     * 打包完成
     * @param deliveryTaskCode
     * @return
     */
    private String packFinsh(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode){
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        params.put("trayNums",0);
        LogUtil.info("【wms出库】打包完成");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API44.getApi(),params);
    }
    public String confirmStock(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode){
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        LogUtil.info("【wms出库】确认出库");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API45.getApi(),params);
    }
    private String confirmSign(ClientLoginDTO clientLoginDTO,String deliveryTaskCode){
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        LogUtil.info("【wms出库】确认签收");
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO)).doPostJson(WmsAPI.WMS_API46.getApi(),params);
    }

    /**
     * 查询批次库存详情
     * @param wmsLoginDTO
     * @param batchCode
     * @return
     */
    private String getBactchInventory(WMSLoginDTO wmsLoginDTO,String batchCode){
        JSONObject params = new JSONObject();
        params.put("pkgCode",batchCode);
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API51.getApi(),params);
    }

    private int getRemainAmounts(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode,Integer deliveryType,DeliverStatus deliverStatus){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            LogUtil.info(e.getMessage());
            Thread.currentThread().interrupt();
        }
        String res = searchTaskPage(wmsLoginDTO, deliveryTaskCode, deliverStatus, deliveryType);
        List<String> batchCodes = new ArrayList<>();
        JSONArray pkgCodeLists = JsonUtil.extractJSONArray(res, "data.records[0].taskDetailList[*].pkgCodeList");
        int remainAmounts = 0;
        for (int i=0;i<pkgCodeLists.size();i++){
            batchCodes.addAll(pkgCodeLists.getJSONArray(i));
        }
        for (String s:batchCodes){
            res = getBactchInventory(wmsLoginDTO,s);
            remainAmounts += JsonUtil.extractInteger(res, "data.records[0].remainAmount");
        }
        return remainAmounts;
    }

    /**
     * 打包完成后查看单据总共发货数
     * @param wmsLoginDTO
     * @param deliveryTaskCode
     * @param deliveryType
     * @return
     */
    private int getDeliverNums(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode,Integer deliveryType){
        String res = searchTaskPage(wmsLoginDTO, deliveryTaskCode, DeliverStatus.DELIVER_STATUS4, deliveryType);
        JSONArray deliveryNums = JsonUtil.extractJSONArray(res, "data.records[0].taskDetailList[*].deliveryNums");
        int nums = 0;
        for (int i=0;i<deliveryNums.size();i++){
            nums+=deliveryNums.getIntValue(i);
        }return nums;
    }


    /**
     * 查询审单列表
     * @param platformOrderNo 订单编号
     * @param deliveryType 0-fba发货，1-大包发货，2-小包发货
     * @return
     */
    private String searchReviewPage(WMSLoginDTO wmsLoginDTO,String platformOrderNo,Integer deliveryType){
        JSONObject params = new JSONObject();
        params.replace("current",1);
        params.replace("deliveryTaskCode","");
        params.replace("deliveryType",deliveryType);
        params.replace("pageNum",1);
        params.replace("pageSize",50);
        params.replace("platformOrderNo",platformOrderNo);
        params.replace("processingStatus",0);
        params.replace("total",1008);
        LogUtil.info("【wms出库】查询审单列表");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API52.getApi(), params);
    }

    /**
     * 修改货代公司
     * @param deliveryTaskCode 订单编号
     * @param wmsIntForwarderConfigId
     * @return
     */
    private String modifyForwarder(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode,String wmsIntForwarderConfigId){
        JSONObject params = new JSONObject();
        params.put("deliveryTaskCode",deliveryTaskCode);
        params.put("wmsIntForwarderConfigId",wmsIntForwarderConfigId);
        LogUtil.info("【wms出库】修改货代公司"+ params);
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API55.getApi(), params);
    }

    /**
     * 修改D2C发货单重量
     * @param deliveryBoxId 订单编号
     * @param deliveryTaskCode 发货任务编号
     * @param insidePackCode 内部打包编号
     * @return
     */
    private String weightEdit(WMSLoginDTO wmsLoginDTO, String deliveryBoxId, String deliveryTaskCode, String insidePackCode){
        JSONObject params = new JSONObject();
        params.put("deliveryBoxId", deliveryBoxId);
        params.put("deliveryTaskCode", deliveryTaskCode);
        params.put("insidePackCode", insidePackCode);
        params.put("weight", 100); //重量（克）
        LogUtil.info("【wms出库】修改D2C发货单重量"+ params);
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API56.getApi(), params);
    }

    /**
     * 删除库存
     * @param productskus sku
     * @param customerShopId 店铺id
     * @return
     */
    public String deleteShopSku(WMSLoginDTO wmsLoginDTO, String productskus, String customerShopId){

        String[] productskuSplit =  productskus.split(",");

        for(int i=0;i<productskuSplit.length;i++){
            ToolsUtil.sleep(1000);
            JSONObject params = new JSONObject();

            params.put("shopProductSku","");
            params.put("productSku",productskuSplit[i]);
            params.put("customerShopId",customerShopId);
            params.put("bizNo","232360");
            params.put("reason","客户要求删除库存");
            LogUtil.info("删除库存");

//            return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.DELETE_SHOP_SKU.getApi(), params);
            try {
                return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson("https://gateway-prod.theckb.com/wms/back/clearStock", params);
            }catch(Exception e){
                e.printStackTrace();
            }
            continue;

        }
        return null;

    }

    /**
     * 查询国际发货单信息
     * @param platformOrderNo 订单号
     * @return wmsDeliveryTaskInfo
     */
    public JSONArray getWmsDeliveryTaskInfo(String platformOrderNo){
        JSONArray wmsDeliveryTaskInfo = new JSONArray();
        List<JSONObject> sql006 = DBUtil.select("WMS-根据发货单号或平台订单号查寻发货单", new ContentDTO("",platformOrderNo),new ContentDTO("",platformOrderNo));
        List<String> deliveryTaskCodeList = sql006.stream()
                .map(obj -> obj.getString("delivery_task_code"))
                .collect(Collectors.toList());

        for (String deliveryTaskCode:deliveryTaskCodeList){
            JSONObject wmsDeliveryTask = new JSONObject();
            //根据国际发货单号查询国际物流单号
            List<JSONObject> sql024 = DBUtil.select("WMS-根据国际发货单查询发货任务物流信息", new ContentDTO("",deliveryTaskCode));
            List<String> logisticsCodeList = sql024.stream()
                    .map(obj -> obj.getString("logistics_code"))
                    .collect(Collectors.toList());
            wmsDeliveryTask.put("deliveryTaskCode",deliveryTaskCode);
            wmsDeliveryTask.put("logisticsCodeList",new JSONArray(logisticsCodeList));
            wmsDeliveryTaskInfo.add(wmsDeliveryTask);
        }

        return wmsDeliveryTaskInfo;
    }

    /**
     * 查询国际发货单信息
     * @param deliveryTaskCode 国际发货单号
     * @return wmsDeliveryTaskInfo
     */
    private DeliverTaskRespDTO getDeliveryInfo(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode){
        Map<String, String> params = new HashMap<>();
        params.put("deliveryTaskCode", deliveryTaskCode);
        String json = JsonUtil.extractString(new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_AP160.getApi(), params), "data");
        DeliverTaskRespDTO deliverTaskRespDTO = gson.fromJson(json, DeliverTaskRespDTO.class);
        return deliverTaskRespDTO;
    }

    /**
     * 担当确认国际发货单
     * @param deliveryTaskCode 国际发货单号
     * @return wmsDeliveryTaskInfo
     */
    private String managerConfirm(WMSLoginDTO wmsLoginDTO,String deliveryTaskCode){
        DeliverTaskRespDTO deliveryInfo = getDeliveryInfo(wmsLoginDTO, deliveryTaskCode);
        List<DeliveryTaskAddressRespDTO> deliveryTaskAddressList = deliveryInfo.getDeliveryTaskAddressList();
        DeliveryTaskAddressRespDTO declarationAddress = deliveryTaskAddressList.stream()
                .filter(item -> Objects.equals(item.getAddressType(), AddressTypeEnum.declaration.getCode()))
                .findFirst().orElse(null);
        DeliveryTaskAddressRespDTO receiverAddress = deliveryTaskAddressList.stream()
                .filter(item -> Objects.equals(item.getAddressType(), AddressTypeEnum.receiver.getCode()))
                .findFirst().orElse(null);
        Integer deliveryType = deliveryInfo.getDeliveryType();
        Integer managerConfirmStatus = deliveryInfo.getManagerConfirmStatus();
        if(deliveryType != 2 && managerConfirmStatus == 0){
            ManagerConfirmReqDTO managerConfirmReqDTO = new ManagerConfirmReqDTO();
            managerConfirmReqDTO.setDeliveryTaskCode(deliveryTaskCode);
            managerConfirmReqDTO.setDeclarationAddress(CopyUtils.copyObject(declarationAddress,com.ckbs.wms.client.dto.req.DeliveryTaskAddressCreateDTO.class));
            managerConfirmReqDTO.setReceiverAddress(CopyUtils.copyObject(receiverAddress,com.ckbs.wms.client.dto.req.DeliveryTaskAddressCreateDTO.class));
            LogUtil.info("【wms出库】担当确认国际发货单");
            return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API61.getApi(), managerConfirmReqDTO);
        }
        return null;
    }

    /**
     * 运行波次
     */
    public String runDeliveryWave(WMSLoginDTO wmsLoginDTO, String waveCode) {
        HashMap<String, Object> param = new HashMap<>();
        param.put("waveCode", waveCode);
        LogUtil.info("【wms出库】运行波次");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPost(WmsAPI.WMS_API64.getApi(), param);
    }

    /**
     * 创建波次
     */
    private String createDeliveryWave(WMSLoginDTO wmsLoginDTO, DeliveryWaveCreateReq deliveryWaveCreateReq){
        LogUtil.info("【wms出库】创建波次");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API63.getApi(), deliveryWaveCreateReq);
    }

    /**
     * 给定一个发货单号或平台单号进行审核新
     */
    public boolean singleReview(WMSLoginDTO wmsLoginDTO,String orderNo){
        String deliveryReviewPo = getDeliveryReview(orderNo);
        if ("{}".equals(deliveryReviewPo)){
            return false;
        }
        String deliveryReviewCode = JsonUtil.extractString(deliveryReviewPo,"delivery_review_code");
        String intForwarderConfigId = JsonUtil.extractString(deliveryReviewPo,"int_forwarder_config_id");
        String itIntShipConfigId = JsonUtil.extractString(deliveryReviewPo,"int_ship_config_id");
        Integer processingStatus = JsonUtil.extractInteger(deliveryReviewPo,"processing_status");

        if(processingStatus > 0){
            return true;
        }

        JSONObject params = new JSONObject();
        params.put("auditIntForwarderConfigId",intForwarderConfigId);
        params.put("auditIntShipConfigId",itIntShipConfigId);
        params.put("auditRemark","审单备注");
        params.put("auditType",0);
        params.put("deliveryReviewCode",deliveryReviewCode);
        params.put("intForwarderConfigId",intForwarderConfigId);

        //审单
        singleReview(wmsLoginDTO,params);
        return true;
    }

    /**
     * 给定一个发货单号或平台单号查询审单表
     */
    private String getDeliveryReview(String orderNo) {
        return DBUtil.selectOne("WMS-根据订单号或国际发货单号查询发货审单表", new ContentDTO("deliveryTaskCode", orderNo), new ContentDTO("platformOrderNo", orderNo)).toJSONString();
    }
    /**
     * 国际发货单待处理-拣货完成
     */
    public JSONObject toPickedProcess(WMSLoginDTO wmsLoginDTO, String deliveryTaskCode) {
        //通过sql查询发货单号
        JSONObject object = DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单", new ContentDTO("", deliveryTaskCode));
        Integer singleProduct = object.getInteger("single_product");
        Integer deliveryType = object.getInteger("delivery_type");
        Integer deliveryStatus = object.getInteger("delivery_status");

        if(deliveryStatus == 0){
            //创建波次
            DeliveryWaveCreateReq deliveryWaveCreateReq = new DeliveryWaveCreateReq();
            deliveryWaveCreateReq.setDeliveryType(deliveryType);
            deliveryWaveCreateReq.setConditionEndTime(new Date());
            deliveryWaveCreateReq.setSingleProduct(singleProduct);
            deliveryWaveCreateReq.setPickTaskLimit(20);
            deliveryWaveCreateReq.setConditionDeliveryTaskCodes(Collections.singletonList(deliveryTaskCode));
            String waveCode = JsonUtil.extractString(createDeliveryWave(wmsLoginDTO,deliveryWaveCreateReq), "data");
            //运行波次生成拣货批次
            runDeliveryWave(wmsLoginDTO,waveCode);
        }

        String pickContainerCode ="";
        String allotContainerCode = "无需分拣";
        if(deliveryStatus == 0 || deliveryStatus == 1){
            //根据国际发货单查询拣货批次
            JSONObject wmsDeliveryPickTask = DBUtil.selectOne(SniffSql.SQL005.getAlias(), new ContentDTO("", deliveryTaskCode));
            String batchCode = wmsDeliveryPickTask.getString("batch_code");
            //根据拣货批次执行拣货
            pickContainerCode = pickingProcess(wmsLoginDTO,batchCode);
            //查询容器状态，如果为【待分拣】，进行分拣
            Integer containerBizStatus = getContainerBizStatus(wmsLoginDTO,pickContainerCode);
            if(containerBizStatus == 4){
                AllotProcess(wmsLoginDTO,pickContainerCode);
            }
        }

        //查询拣货任务
        JSONObject wmsDeliveryPickTask = DBUtil.selectOne(SniffSql.SQL005.getAlias(), new ContentDTO("", deliveryTaskCode));
        String batchCode = wmsDeliveryPickTask.getString("batch_code");
        pickContainerCode = wmsDeliveryPickTask.getString("pick_container_code");
        allotContainerCode = wmsDeliveryPickTask.getString("allot_container_code");
        //查询分拣详情
        JSONObject wmsDeliveryTaskAllotDetail = DBUtil.selectOne(SniffSql.SQL031.getAlias(), new ContentDTO("", deliveryTaskCode));
        String childContainerCode = wmsDeliveryTaskAllotDetail.getString("container_code");

        JSONObject pickedInfo = new JSONObject();
        pickedInfo.put("childContainerCode",childContainerCode);
        pickedInfo.put("wmsUsername",wmsUsername);
        pickedInfo.put("batchCode",batchCode);
        pickedInfo.put("pickContainerCode",pickContainerCode);
        pickedInfo.put("allotContainerCode",allotContainerCode);
        return pickedInfo;
    }

    /**
     * PDA拣货
     */
    private String pickingProcess(WMSLoginDTO wmsLoginDTO, String batchCode) {
        //获取未使用容器
        String containerCode = getContainer(wmsLoginDTO,1,1);
        //绑定拣货容器
        scanBind(wmsLoginDTO, batchCode, containerCode);
        //开始拣货
        String pickTaskCode = startPicking(wmsLoginDTO, batchCode, containerCode);
        //获取待拣货列表
        String res = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGetURL(WmsAPI.WMS_API68.getApi() + batchCode);
        List<String> pkgCodes = JsonUtil.extractMultiT(res, "pkgCode");
        //pkgCode拣货
        pkgCodes.forEach(pkgCode -> picked(wmsLoginDTO,pickTaskCode,pkgCode));
        //完成拣货
        pickFinishNew(wmsLoginDTO,batchCode);
        return containerCode;
    }
    /**
     * PDA分拣
     */
    private String AllotProcess(WMSLoginDTO wmsLoginDTO, String pickContainerCode) {
        //获取未使用状态分拣容器
        String allotContainerCode = getContainer(wmsLoginDTO,1,2);
        //绑定分拣中状态拣货容器
        pickContainerBind(wmsLoginDTO, pickContainerCode);
        //绑定未使用状态分拣容器
        allotContainerBind(wmsLoginDTO, allotContainerCode, pickContainerCode);
        //开始分拣
        String pickTaskCode = startAllot(wmsLoginDTO, pickContainerCode, allotContainerCode);
        //获取未分拣列表
        String json = JsonUtil.extractString(getD2cAllotProgress(wmsLoginDTO,pickTaskCode), "data");
        D2cAllotProgressRespDTO D2cAllotProgressRespDTO = gson.fromJson(json, D2cAllotProgressRespDTO.class);
        List<D2cAllotProgressInfoDTO> D2cAllotProgressInfoList = D2cAllotProgressRespDTO.getUnPickedProgressInfoDTOList();
        //实施分拣
        D2cAllotProgressInfoList.forEach(d2cAllotProgressInfoDTO -> {
            String pkgCode = d2cAllotProgressInfoDTO.getPkgCode();
            Integer unPickedNum = d2cAllotProgressInfoDTO.getUnPickedNums();
            for(int i=0;i<unPickedNum;i++){
                singleProductAllot(wmsLoginDTO, pickTaskCode, pkgCode);
            }
        });
        //分拣完成
        allotFinish(wmsLoginDTO,pickTaskCode);
        return allotContainerCode;
    }

    /**
     * PDA分拣-单品分拣
     */
    private void singleProductAllot(WMSLoginDTO wmsLoginDTO, String pickTaskCode, String pkgCode) {
        JSONObject params = new JSONObject();
        params.put("pickTaskCode",pickTaskCode);
        params.put("pkgCode",pkgCode);
        new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API73.getApi(), params);
    }

    /**
     * PDA分拣-开始分拣
     */
    private String startAllot(WMSLoginDTO wmsLoginDTO, String pickContainerCode, String allotContainerCode) {
        JSONObject params = new JSONObject();
        params.put("allotContainerCode",allotContainerCode);
        params.put("pickContainerCode",pickContainerCode);
        String res = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API72.getApi(), params);
        String pickTaskCode = JsonUtil.extractString(res, "data.pickTaskCode");
        return pickTaskCode;
    }

    /**
     * PDA分拣-绑定待分拣状态拣货容器
     */
    private void pickContainerBind(WMSLoginDTO wmsLoginDTO, String pickContainerCode) {
        JSONObject params = new JSONObject();
        params.put("containerCode",pickContainerCode);
        new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API70.getApi(), params);
    }

    /**
     * PDA分拣-绑定未使用状态分拣容器
     */
    private void allotContainerBind(WMSLoginDTO wmsLoginDTO, String allotContainerCode, String pickContainerCode) {
        JSONObject params = new JSONObject();
        params.put("pickContainerCode",pickContainerCode);
        params.put("allotContainerCode",allotContainerCode);
        new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API71.getApi(), params);
    }

    /**
     * 开始拣货
     */
    private String startPicking(WMSLoginDTO wmsLoginDTO, String batchCode, String containerCode) {
        JSONObject params = new JSONObject();
        params.put("batchCode",batchCode);
        params.put("containerCode",containerCode);
        //开始拣货
        String res = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API67.getApi(), params);
        return JsonUtil.extractString(res, "data.pickTaskCode");
    }

    /**
     * 拣货绑定拣货容器
     */
    private void scanBind(WMSLoginDTO wmsLoginDTO, String batchCode, String  containerCode) {
        //拣货绑定拣货容器
        JSONObject params = new JSONObject();
        params.put("batchCode",batchCode);
        params.put("containerCode",containerCode);
        new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API65.getApi(), params);
    }

    /**
     * 获取容器
     */
    private String getContainer(WMSLoginDTO wmsLoginDTO, Integer bizStatus, Integer containerType) {
        JSONObject json = new JSONObject();
        json.put("bizStatus",bizStatus);
        json.put("containerType",containerType);
        json.put("pageNo",1);
        json.put("pageSize",10);

        String res = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API66.getApi(), json);
        String containerCode = JsonUtil.extractString(res, "data.records[0].containerCode");

        return containerCode;
    }

    /**
     * 获取容器状态
     */
    private Integer getContainerBizStatus(WMSLoginDTO wmsLoginDTO, String containerCode) {
        JSONObject json = new JSONObject();
        json.put("containerCode",containerCode);
        json.put("pageNo",1);
        json.put("pageSize",10);

        String res = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API66.getApi(), json);
        Integer getContainerBizStatus = JsonUtil.extractInteger(res, "data.records[0].bizStatus");

        return getContainerBizStatus;
    }

    /**
     * 拣货完成
     */
    private String pickFinishNew(WMSLoginDTO wmsLoginDTO,String batchCode){
        JSONObject params = new JSONObject();
        params.put("batchCode",batchCode);
        LogUtil.info("【PDA拣货】拣货完成");
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API69.getApi(),params);
    }

    /**
     * 国际发货单-数据插入物流单号
     */
    public String addLogisticsNo(String deliveryTaskCode) {
        String logisticsCode = "SF"+System.currentTimeMillis();
        DBUtil.insertOrUpdate(SniffSql.SQL029.getAlias(), new ContentDTO("logisticsCode",logisticsCode), new ContentDTO("deliveryTaskCode",deliveryTaskCode) );
        return logisticsCode;

    }

    /**
     * 国际发货单-抵扣
     */
    public void batchDeliveryTaskDeduction(WMSLoginDTO wmsLoginDTO, BatchDeliveryDeductionDto batchDeliveryDeductionDto) {
        new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.BATCH_DELIVERY_TASK_DEDUCTION.getApi(),batchDeliveryDeductionDto);
    }

    /**
     * 根据国际发货单查询在途未全部抵扣sku
     */
    public List<JSONObject> getTransitPartialDeduction(String deliveryTaskCode) {
        List<JSONObject> sql030 = DBUtil.select("WMS-根据国际发货单查询在途未全部抵扣sku", new ContentDTO("",deliveryTaskCode));
        return sql030;
    }

    /**
     * 根据国际发货单查询在途未全部抵扣sku
     */
    public JSONObject getDeliveryTaskInfo(String deliveryTaskCode) {
        JSONObject re = new JSONObject();

        JSONObject wmsDeliveryTask = DBUtil.selectOne(SniffSql.SQL006.getAlias(), new ContentDTO("",deliveryTaskCode));
        if (wmsDeliveryTask == null || wmsDeliveryTask.isEmpty()){
            re.put("国际发货单状态","未找到");
            return re;
        }
        Integer deliveryStatus = wmsDeliveryTask.getInteger("delivery_status");
        Integer singleProduct = wmsDeliveryTask.getInteger("single_product");
        Integer deliveryType = wmsDeliveryTask.getInteger("delivery_type");
        re.put("国际发货单类型", DeliveryTypeEnum.getByType(deliveryType).getDesc());
        re.put("国际发货单状态",DeliveryStatusEnum.getByCode(deliveryStatus).getDesc());
        Integer crossDockingFlag = wmsDeliveryTask.getInteger("cross_docking_flag"); //是否越库标志 0-否，1-是
        re.put("是否越库",crossDockingFlag == 1 ? "是":"否");
        Integer interceptStatus = wmsDeliveryTask.getInteger("intercept_status"); //0-无操作 1-挂起 2-取消挂起 默认0
        re.put("是否被拦截",interceptStatus == 1 ? "是":"否");

        DeliverTaskRespDTO deliverTaskRespDTO = getDeliveryInfo(LoginConstant.wmsLoginDTO,deliveryTaskCode);
        if (DeliveryStatusEnum.wait_shelves.getStatus().equals(deliveryStatus)){
            Integer managerConfirmStatus = wmsDeliveryTask.getInteger("manager_confirm_status"); //担当确认状态 0否 1是
            Integer processingStatus = wmsDeliveryTask.getInteger("processing_status"); //审单处理状态(0:待处理 1:待确认 2:已处理)
            String processingStatusStr = getProcessingStatusString(processingStatus);
            Integer shelvesStatus = wmsDeliveryTask.getInteger("shelves_status"); //上架完成状态: 0 否 1 是
            Integer enableDeliveryStatus = wmsDeliveryTask.getInteger("enable_delivery_status"); //可发货状态: 0 否 1 是 订单通知
            re.put("审单状态",processingStatusStr);
            re.put("上架完成状态",shelvesStatus == 1?"是":"否");
            re.put("订单通知可发货状态",enableDeliveryStatus == 1?"是":"否");
            re.put("担当确认状态",managerConfirmStatus == 1?"是":"否");
            return re;
        }

        if(deliveryStatus > -1){
            String logisticsCode = deliverTaskRespDTO.getLogisticsDetailList().isEmpty() ? "" : deliverTaskRespDTO.getLogisticsDetailList().get(0).getLogisticsCode();
            re.put("国际物流单号",logisticsCode.isEmpty() ? "请先获取国际物流单号" : logisticsCode);
        }

        if(DeliveryStatusEnum.picking.getStatus().equals(deliveryStatus) && deliveryType == 2){
            //查询拣货任务
            JSONObject wmsDeliveryPickTask = DBUtil.selectOne(SniffSql.SQL005.getAlias(), new ContentDTO("", deliveryTaskCode));
            String batchCode = wmsDeliveryPickTask.getString("batch_code");
            String pickContainerCode = wmsDeliveryPickTask.getString("pick_container_code");
            String allotContainerCode = wmsDeliveryPickTask.getString("allot_container_code");
            re.put("拣货批次",batchCode);
            re.put("拣货容器",pickContainerCode);
            re.put("分拣容器",allotContainerCode);
        }

        if(DeliveryStatusEnum.packing.getStatus().equals(deliveryStatus)){
            if(deliveryType == 0){
                re.put("FBA装箱",deliveryTaskCode);
            } else if(deliveryType == 1){
                re.put("大件装箱",deliveryTaskCode);
            }else{
                if(crossDockingFlag == 1  || singleProduct == 1){
                    String pkgCode = deliverTaskRespDTO.getTaskDetailList().get(0).getPkgCodeList().get(0);
                    re.put("小件单品打包",pkgCode);
                }else{
                    //查询分拣详情
                    JSONObject wmsDeliveryTaskAllotDetail = DBUtil.selectOne(SniffSql.SQL031.getAlias(), new ContentDTO("", deliveryTaskCode));
                    String childContainerCode = wmsDeliveryTaskAllotDetail.getString("container_code");
                    re.put("小件多品打包",childContainerCode); //分拣子容器
                }
            }
        }
        return re;
    }

    private String getProcessingStatusString(Integer status) {
        // 创建一个Map来存储状态码和对应的字符串描述
        Map<Integer, String> statusMap = new HashMap<>();
        statusMap.put(0, "待处理");
        statusMap.put(1, "待确认");
        statusMap.put(2, "已处理");

        // 从Map中获取对应的字符串描述，如果找不到则返回空字符串或者null
        return statusMap.getOrDefault(status, ""); // 使用getOrDefault可以避免NullPointerException
    }
}